/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.entities;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.zhiqim.httpd.HttpEntity;
import org.zhiqim.httpd.HttpException;
import org.zhiqim.httpd.HttpHeader;
import org.zhiqim.httpd.HttpSender;
import org.zhiqim.kernel.util.Arrays;
import org.zhiqim.kernel.util.Lists;
import org.zhiqim.kernel.util.Validates;

/**
 * 跨域实现
 *
 * @version v8.0.1 @author zouzhigang 2021年7月26日 新建与整理
 */
public class OptionsEntity implements HttpEntity
{
    private List<String> headers;
    private String methods;
    private String origin;
    private int maxAge;
    
    @Override
    public boolean isMatch(String pathInContext)
    {//全匹配，在handle中处理
        return true;
    }
    
    @Override
    public void handle(HttpHeader header, HttpSender sender) throws HttpException, IOException
    {
        if (headers == null || methods == null || origin == null)
        {//不支持的方法
            sender.sendError(_405_METHOD_NOT_ALLOWD_);
            return;
        }
        
        String requests = header.getHeader(_ACCESS_CONTROL_REQUEST_HEADERS_);
        if (Validates.isEmptyBlank(requests))
        {//没有请求头数据的不是有效的请求
            sender.sendError(_400_BAD_REQUEST_);
            return;
        }
        
        if (!headers.isEmpty())
        {//要求不为空，则检查是否可接受
            String[] reqs = Arrays.toStringArray(requests);
            for (String req : reqs)
            {
                if (!headers.contains(req))
                {//不在配置中
                    sender.sendError(_406_NOT_ACCEPTABLE_);
                    return;
                }
            }
        }

        //返回结果
        sender.addHeader(_ACCESS_CONTROL_ALLOW_HEADERS_, requests);
        sender.addHeader(_ACCESS_CONTROL_ALLOW_METHODS_, methods);
        sender.addHeader(_ACCESS_CONTROL_ALLOW_ORIGIN_, origin);
        if (maxAge > 0 || maxAge == -1)
        {//有配置最大时长，-1表示每次都需要
            sender.addHeader(_ACCESS_CONTROL_MAX_AGE_, maxAge);
        }
        
        sender.setContentType(_TEXT_PLAIN_UTF_8_);
        sender.setStatus(_204_NO_CONTENT_);
    }

    public void setHeaders(String headers)
    {
        if (Validates.isEmptyBlank(headers))
            return;
        
        if ("*".equals(headers))
            this.headers = new ArrayList<>();
        else
            this.headers = Lists.toStringList(headers);
    }

    public void setMethods(String methods)
    {
        if (Validates.isEmptyBlank(methods))
            return;
        
        if ("*".equals(methods))
            this.methods = "GET, POST, HEAD, OPTIONS, PUT, DELETE";
        else
            this.methods = methods;
    }

    public void setOrigin(String origin)
    {
        if (Validates.isEmptyBlank(origin))
            return;
        
        this.origin = origin;
    }
    
    public void setMaxAge(int maxAge)
    {
        this.maxAge = maxAge;
    }
}